from rest_framework.viewsets import ViewSet
from course import models
from rest_framework.response import Response
from rest_framework import status
from django_redis import get_redis_connection
from luffy.settings import contants

# IsAuthenticated 即rest_framework 提供的认证是否登录成功的认证类
from rest_framework.permissions import IsAuthenticated
import logging

logger = logging.getLogger()


class CartAPIView(ViewSet):
    # 登录成功才有权限访问
    permission_classes = [IsAuthenticated, ]

    def add(self, request):
        """
        添加到预购课
        :return:
        """
        course_id = request.data.get('course_id')

        user_id = request.user.id

        # 为预购课中的课程设置有效期和是否被选中设置默认值
        expire = 0  # 0代表永久有效

        # True 代表选中，即默认用户加入预购课的课程处于被选中状态
        is_selected = True

        try:
            models.Course.objects.get(pk=course_id)
        except models.Course.DoesNotExist:
            return Response({'msg': '课程不存在，请重新选择'}, status=status.HTTP_400_BAD_REQUEST)

        redis_conn = get_redis_connection('cart')

        try:
            pipe = redis_conn.pipeline()
            pipe.multi()
            pipe.hset('cart_%s' % user_id, course_id, expire)

            pipe.sadd('selected_%s' % user_id, course_id)

            pipe.execute()

            # hlen 针对 哈希类型的依据键取值的数量（即预购课中的课程数量）
            course_num = redis_conn.hlen('cart_%s' % user_id)
        except:
            logger.error('课程添加失败！')
            return Response({'msg': '课程添加失败！'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

        return Response({'msg': '课程添加成功！', 'course_num': course_num})

    def cart_list(self, request):
        """预购课数据展示"""
        user_id = request.user.id

        redis_conn = get_redis_connection('cart')

        cart_data_dict = redis_conn.hgetall('cart_%s' % user_id)
        selected_course_data = redis_conn.smembers('selected_%s' % user_id)

        data = []
        try:
            for course_id_bytes, expire_bytes in cart_data_dict.items():
                course_id = int(course_id_bytes.decode())
                expire_id = int(expire_bytes.decode())

                course_obj = models.Course.objects.get(pk=course_id)
                data.append({
                    'id': course_obj.id,
                    'course_img': contants.SERVER_HOST + course_obj.course_img.url,
                    'name': course_obj.name,
                    'origin_price': course_obj.price,
                    'real_price': course_obj.real_price(expire_id),
                    'expire_id': expire_id,
                    'expire_list': course_obj.expire_list,
                    'is_selected': course_id_bytes in selected_course_data,
                })
        except:
            return Response('获取课程数据失败', status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response(data)

    def change_course_selected(self, request):
        """
        改变课程勾选状态
        :param request:
        :return:
        """
        user_id = request.user.id
        course_id = request.data.get('course_id')

        # 提交过来的'is_selected'的值是 True， 则在redis库中'selected_user_id' 添加一条记录，反之则删除一条记录
        is_selected = request.data.get('is_selected')

        try:
            models.Course.objects.get(pk=course_id)
        except models.Course.DoesNotExist:
            return Response({'msg': '所选课程不存在！'}, status=status.HTTP_400_BAD_REQUEST)

        redis_conn = get_redis_connection('cart')
        if is_selected:
            redis_conn.sadd(f'selected_{user_id}', course_id)
        else:
            redis_conn.srem(f'selected_{user_id}', course_id)
        return Response({'msg': '勾选状态切换成功！'})

    def change_expire(self, request):
        """
        切换课程有效期
        :param request:
        :return:
        """
        user_id = request.user.id
        course_id = request.data.get('course_id')
        expire_id = request.data.get('expire_id')

        try:
            course = models.Course.objects.get(pk=course_id)
            # expire_id = 0 表示永久有效，永久有效数据没有保存在CourseExpire表中
            if expire_id > 0:

                expire_obj = models.CourseExpire.objects.filter(is_show=True, is_deleted=False, id=expire_id)
                if not expire_obj:
                    raise models.Course.DoesNotExist

        except models.Course.DoesNotExist:

            return Response({'msg': '所选课程或课程有效期不存在！'}, status=status.HTTP_400_BAD_REQUEST)

        redis_conn = get_redis_connection('cart')
        redis_conn.hset('cart_%s' % user_id, course_id, expire_id)

        real_price = course.real_price(expire_id)
        return Response({'msg': '课程有效期切换成功!', 'real_price': real_price})

    def delete_course(self, request):
        """
        删除预购课中的选中课程
        :param request:
        :return:
        """
        user_id = request.user.id
        course_id = request.query_params.get('course_id')

        try:
            course = models.Course.objects.get(pk=course_id)
        except models.Course.DoesNotExist:
            return Response({'msg': '删除课程不存在！'}, status=status.HTTP_400_BAD_REQUEST)

        redis_conn = get_redis_connection('cart')
        pipe = redis_conn.pipeline()
        pipe.multi()
        pipe.hdel(f'cart_{user_id}', course_id)
        pipe.srem(f'selected_{user_id}', course_id)
        pipe.execute()

        # hlen 针对 哈希类型的依据键取值的数量（即预购课中的课程数量）
        course_num = redis_conn.hlen('cart_%s' % user_id)

        return Response({'msg': '课程删除成功！', 'course_num': course_num})

    def get_selected_course(self, request):
        """获取购物车中勾选的课程"""

        user_id = request.user.id
        redis_conn = get_redis_connection('cart')

        cart_data_dict = redis_conn.hgetall("cart_%s" % user_id)
        selected_course_data = redis_conn.smembers("selected_%s" % user_id)

        data = []  # 存放勾选中的课程相关数据
        total_price = 0
        real_total_price = 0
        for course_id_bytes, expire_bytes in cart_data_dict.items():

            course_id = int(course_id_bytes.decode())
            expire_id = int(expire_bytes.decode())
            if course_id_bytes in selected_course_data:
                try:
                    course_obj = models.Course.objects.get(pk=course_id)
                except:
                    continue

                expire_text = '永久有效'

                try:
                    if expire_id > 0:
                        expire_obj = models.CourseExpire.objects.get(is_show=True, is_deleted=False, id=expire_id)

                        expire_text = expire_obj.expire_text

                except models.CourseExpire.DoesNotExist:

                    return Response({'msg': '有效期不存在！'}, status=status.HTTP_400_BAD_REQUEST)

                real_price = course_obj.real_price(expire_id)

                data.append({
                    'id': course_obj.id,
                    'course_img': contants.SERVER_HOST + course_obj.course_img.url,
                    'name': course_obj.name,
                    'real_price': real_price,
                    'expire_text': expire_text,
                    'discount_name': course_obj.discount_name,
                    'origin_price': course_obj.price,
                })

                total_price += float(course_obj.price)
                real_total_price += float(real_price)

        return Response({"select_course_list": data, "total_price": total_price, 'real_total_price': real_total_price})
